package com.astrob.model;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import com.astrob.naviframe.Start;

import java.util.ArrayList;

public class RoutePlanDataHandle {
	// dests manage
	private ArrayList<HistoryData> mDests = new ArrayList<HistoryData>();

	public ArrayList<HistoryData> getDests() {
		return mDests;
	}

	public void setDestsfromNavDest() {
		mDests.clear();
		if (Start.getInstance().MapKit().mNavDest == null
				|| Start.getInstance().MapKit().mNavDest.length < 1)
			return;
		
		for(int i = 0; i < Start.getInstance().MapKit().mNavDest.length; i++) {
			HistoryData data = new HistoryData();
			data.lat = Start.getInstance().MapKit().mNavDest[i].pos.lat;
			data.lon = Start.getInstance().MapKit().mNavDest[i].pos.lon;
			data.name = Start.getInstance().MapKit().mNavDest[i].name;
			data.countryID = "CN";
			mDests.add(data);
		}
	}

	public void addDest(HistoryData dest) {
		if (changeStart_) {
			changeStart_ = false;
			setStart(dest);
		} else {
			mDests.add(dest);
			HistoryFileHandle.getInstance().add(dest);
		}		
	}

	public void changeUp(int pos) {
		if (pos == 0)
			return;

		int destIndex = pos - 1;
		if (destIndex < 0 || destIndex >= mDests.size())
			return;
		
		HistoryData selectedData = mDests.get(destIndex);
		if (destIndex == 0) {
			HistoryData lastStart = getStart();
			setStart(selectedData);
			mDests.set(0, lastStart);
		} else {
			HistoryData upData = mDests.get(destIndex - 1);
			mDests.set(destIndex - 1, selectedData);
			mDests.set(destIndex, upData);
		}

	}
	
	public boolean changeDest(HistoryData newDest, int nChangeIndex) {
		if (nChangeIndex < 0 || nChangeIndex >= mDests.size()) {
			return false;
		}
		mDests.set(nChangeIndex, newDest);
		HistoryFileHandle.getInstance().add(newDest);
		return true;
	}
	
	public void delDest(int pos) {
		if (pos < 0 || pos > mDests.size()) {
			return;
		}
		mDests.remove(pos);
	}
	
	public void logDatas() {
		Log.d("THZ", "start:" + mStart.name);
		Log.d("THZ", "dests size: " + mDests.size());
		for (int i=0; i<mDests.size(); i++) {
			Log.d("THZ", "dest[" + i + "] :" + mDests.get(i).name);
		}
	}

	public void moveUp(int pos) {
		if (pos <= 0) {
			return;
		}
		HistoryData data = mDests.get(pos);
		mDests.remove(pos);
		mDests.add(pos - 1, data);
	}

	public void moveDown(int pos) {
		if (pos < 0 || pos >= mDests.size() - 1) {
			return;
		}
		HistoryData data = mDests.get(pos);
		mDests.remove(pos);
		mDests.add(pos + 1, data);
	}

	public void clearDests() {
		mDests.clear();
	}

	// start manage
	private HistoryData mStart = null;

	public void setStart(HistoryData start) {
		mStart = start;
		HistoryFileHandle.getInstance().add(start);
	}

	public HistoryData getStart() {
		if (mStart == null || mStart.lon == 0) {
			mStart = new HistoryData();
			double dlon = SystemSetFileHandle.getInstance().getSystemSet().previewLon;
			double dlat = SystemSetFileHandle.getInstance().getSystemSet().previewLat;
			mStart.lon = dlon;
			mStart.lat = dlat;
			mStart.name = "当前位置";
			mStart.countryID = "CN";
		}
		return mStart;
	}

	public void clearStart() {
		setStart(null);
	}

	// ----
	private static String DATAPATH = Start.RUNDIR + "/RoutePlan.db";
	private static RoutePlanDataHandle instance = new RoutePlanDataHandle();
	private ArrayList<RoutePlanIndex> mListRoutePlan = new ArrayList<RoutePlanIndex>();

	public static RoutePlanDataHandle getInstance() {
		return instance;
	}

	private RoutePlanDataHandle() {

	}
	
	private boolean changeStart_ = false;
	
	public void setChangeStart(boolean changeStart) {
		changeStart_ = changeStart;
	}
	
	public RoutePlanIndex detailOne = new RoutePlanIndex();

	private SQLiteDatabase mSQL;
	private static final String TABLE_NAME = "RoutePlanList";
	private static final String ID = "id";
	private static final String TEXT = "name";
	private static final String COUNTRYID = "countryid";
	private static final String TIME = "time";

	public boolean load(Context context) {
		try {
			mSQL = SQLiteDatabase.openOrCreateDatabase(DATAPATH, null);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		try {
			// create table
			String sql = "CREATE TABLE " + TABLE_NAME + " (" + ID
					+ " INTEGER PRIMARY KEY AUTOINCREMENT," + TEXT + " TEXT,"
					+ COUNTRYID + " TEXT,"
					+ TIME + " INTEGER);";
			mSQL.execSQL(sql);
		} catch (Exception e) {
			readRPIndexDB();
		}
		return true;
	}

	public void close() {
		mSQL.close();
	}

	private void readRPIndexDB() {
		mListRoutePlan.clear();
		Cursor cursor = mSQL.query(TABLE_NAME, null, null, null, null, null,
				TIME + " DESC");
		while (cursor.moveToNext()) {
			RoutePlanIndex index = new RoutePlanIndex();
			index.setName(cursor.getString(1));
			index.setTimeStamp(cursor.getLong(3));
			index.countryID = cursor.getString(2);
			mListRoutePlan.add(index);
		}
	}

	public ArrayList<RoutePlanIndex> getRoutePlanIndexList() {
		ArrayList<RoutePlanIndex> routelist = new ArrayList<RoutePlanIndex>();
		for (int i = 0; i < mListRoutePlan.size(); i++) {
			RoutePlanIndex data = mListRoutePlan.get(i);
			if (data.countryID
					.compareToIgnoreCase("CN") == 0) {
				routelist.add(data);
			}
		}

		return routelist;
	}

	// get route plan data
	private ArrayList<HistoryData> mRoutePlan = new ArrayList<HistoryData>();

	public ArrayList<HistoryData> loadRoutePlan(int pos) {
		mRoutePlan.clear();
		if (pos < 0 || pos >= mListRoutePlan.size()) {
			return null;
		}
		RoutePlanIndex index = mListRoutePlan.get(pos);
		String sqlName = "A" + index.getTimeStamp() + "";
		try {
			// open table
			Cursor cursor = mSQL.query(sqlName, null, null, null, null, null,
					null, null);
			// read table
			while (cursor.moveToNext()) {
				HistoryData data = new HistoryData();
				LonLat ll = new LonLat();
				ll.SetLonLat(cursor.getDouble(1), cursor.getDouble(2));
				data.setLl(ll);
				data.setName(cursor.getString(3));
				data.setAddress(cursor.getString(4));
				data.setPhoneNum(cursor.getString(5));
				data.setCurrentTimeMillis(cursor.getLong(6));
				data.countryID = cursor.getString(7);
				mRoutePlan.add(data);
			}

		} catch (Exception e) {
		}
		// return data
		return mRoutePlan;
	}
	
	public ArrayList<HistoryData> loadRoutePlan(RoutePlanIndex index) {
		mRoutePlan.clear();
		String sqlName = "A" + index.getTimeStamp() + "";
		try {
			// open table
			Cursor cursor = mSQL.query(sqlName, null, null, null, null, null,
					null, null);
			
			LonLat lastLL = new LonLat();
			int i = 0;
			int distance = 10000;
			// read table
			while (cursor.moveToNext()) {
				HistoryData data = new HistoryData();
				LonLat ll = new LonLat();
				ll.SetLonLat(cursor.getDouble(1), cursor.getDouble(2));
				data.setLl(ll);
				data.setName(cursor.getString(3));
				data.setAddress(cursor.getString(4));
				data.setPhoneNum(cursor.getString(5));
				data.setCurrentTimeMillis(cursor.getLong(6));
				data.countryID = cursor.getString(7);
				if (i > 0) {
					distance = (int) Start.getInstance().MapKit().getDistance(lastLL, ll);
				}
				lastLL = ll;
				i++;	
				if (distance > 100) {
					mRoutePlan.add(data);
				}				
			}

		} catch (Exception e) {
		}
		// return data
		return mRoutePlan;
	}

	// add route plan
	public boolean addRoutePlan(ArrayList<HistoryData> dests, String strRouteName) {
		int size = dests.size();
		if (size <= 0) {
			return false;
		}
		String name = strRouteName;
		if (name == null || name.length() == 0) {
			name = dests.get(0).getName();
			for (int i = 1; i < size; ++i) {
				name += "-";
				name += dests.get(i).getName();
			}
		}
		
		long timeStamp = System.currentTimeMillis();
		String condition = "name = \"" + name + "\"";
		// search name
		Cursor cursor = mSQL.query(TABLE_NAME, new String[] { "name" },
				condition, null, null, null, null);
		// if find, update timestamp
		if (cursor.moveToNext()) {
			ContentValues args = new ContentValues();
			args.put(TIME, timeStamp);
			mSQL.update(TABLE_NAME, args, condition, null);
			String tableName = "A" + timeStamp + "";
			try {
				mSQL.execSQL("DROP TABLE" + tableName);
			} catch (Exception e) {
			}
			// update list, first to delete it, then insert to header
			int listsize = mListRoutePlan.size();
			int pos = 0;
			for (int i = 0; i < listsize; ++i) {
				RoutePlanIndex index = mListRoutePlan.get(i);
				if (index.getName().compareTo(name) == 0) {
					pos = i;
					break;
				}
			}
			mListRoutePlan.remove(pos);
			RoutePlanIndex index = new RoutePlanIndex();
			index.setName(name);
			index.setTimeStamp(timeStamp);
			index.countryID = "CN";
			mListRoutePlan.add(0, index);
		}
		// else insert to index
		else {
			// insert data
			ContentValues args = new ContentValues();
			args.put(TEXT, name);
			args.put(TIME, timeStamp);
			args.put(COUNTRYID, "CN");
			mSQL.insert(TABLE_NAME, null, args);
			// update list
			RoutePlanIndex index = new RoutePlanIndex();
			index.setName(name);
			index.setTimeStamp(timeStamp);
			index.countryID = "CN";
			mListRoutePlan.add(0, index);
		}
		// create new table to add new dests
		String sqlName = "A" + timeStamp + "";
		// create table
		String sql = "CREATE TABLE "
				+ sqlName
				+ " ("
				+ "id INTEGER PRIMARY KEY AUTOINCREMENT,"
				+ "lon REAL,lat REAL,name TEXT,address TEXT,phoneNum TEXT,timestamp INTEGER,countryid TEXT);";
		try {
			mSQL.execSQL(sql);
			// insert data
			for (int i = 0; i < size; ++i) {
				HistoryData data = dests.get(i);
				ContentValues cv = new ContentValues();
				cv.put("lon", data.getLl().GetLon());
				cv.put("lat", data.getLl().GetLat());
				cv.put("name", data.getName());
				cv.put("address", data.getAddress());
				cv.put("phoneNum", data.getPhoneNum());
				cv.put("timestamp", data.currentTimeMillis());
				cv.put("countryid", "CN");
				mSQL.insert(sqlName, null, cv);
			}
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	// delete route plan
	public void deleteRoutePlan(int pos) {
		RoutePlanIndex index = mListRoutePlan.get(pos);
		try {
			// delete index item and destroy table
			String sqlName = "A" + index.getTimeStamp() + "";
			String sql = "DELETE FROM " + TABLE_NAME + " WHERE " + TIME + " = "
					+ index.getTimeStamp();
			mSQL.execSQL(sql);
			mSQL.execSQL("DROP TABLE " + sqlName);
		} catch (Exception e) {
			e.printStackTrace();
		}
		mListRoutePlan.remove(pos);
	}
	
	public void deleteRoutePlan(RoutePlanIndex index) {
		try {
			// delete index item and destroy table
			String sqlName = "A" + index.getTimeStamp() + "";
			String sql = "DELETE FROM " + TABLE_NAME + " WHERE " + TIME + " = "
					+ index.getTimeStamp();
			mSQL.execSQL(sql);
			mSQL.execSQL("DROP TABLE " + sqlName);
		} catch (Exception e) {
			e.printStackTrace();
		}
		mListRoutePlan.remove(index);
	}

	public void removeAllRoutePlan() {
		if (mListRoutePlan == null) {
			readRPIndexDB();
		}

		if (mListRoutePlan != null) {

			while (!mListRoutePlan.isEmpty()) {
				deleteRoutePlan(0);
			}
		}
	}
	
	public String getRoutePlanName(int pos) {
		if (pos >= 0 && pos < mListRoutePlan.size()){
			RoutePlanIndex index = mListRoutePlan.get(pos);
			return index.getName();
		} else {
			return null;
		}
	}

	public void editRoutePlanName(int pos, String newName) {
		RoutePlanIndex index = mListRoutePlan.get(pos);
		if (index.getName().equals(newName)) {
			return;
		}
		mListRoutePlan.remove(pos);
		index.setName(newName);
		index.countryID = "CN";
		mListRoutePlan.add(pos, index);
		try {
			ContentValues args = new ContentValues();
			args.put(TEXT, newName);
			String condition = "time = \"" + index.getTimeStamp() + "\"";
			mSQL.update(TABLE_NAME, args, condition, null);
		} catch (Exception e) {
		}
	}
	
	public void editRoutePlanName(RoutePlanIndex index, String newName) {
		if (index.getName().equals(newName)) {
			return;
		}
		
		int pos = mListRoutePlan.indexOf(index);
		if (pos < 0 || pos >= mListRoutePlan.size() )
			return;
		
		mListRoutePlan.remove(pos);
		index.setName(newName);
		index.countryID = "CN";
		mListRoutePlan.add(pos, index);
		
		try {
			ContentValues args = new ContentValues();
			args.put(TEXT, newName);
			String condition = "time = \"" + index.getTimeStamp() + "\"";
			mSQL.update(TABLE_NAME, args, condition, null);
		} catch (Exception e) {
		}
	}
}
